home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
201-225
/
214
/
mandelvroom
/
src
/
lens.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
14KB
|
574 lines
/*
* MandelVroom 2.0
*
* (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
*
* All rights reserved.
*
* Permission is hereby granted to distribute this program's source
* executable, and documentation for non-comercial purposes, so long as the
* copyright notices are not removed from the sources, executable or
* documentation. This program may not be distributed for a profit without
* the express written consent of the author Kevin L. Clague.
*
* This program is not in the public domain.
*
* Fred Fish is expressly granted permission to distribute this program's
* source and executable as part of the "Fred Fish freely redistributable
* Amiga software library."
*
* Permission is expressly granted for this program and it's source to be
* distributed as part of the Amicus Amiga software disks, and the
* First Amiga User Group's Hot Mix disks.
*
* contents: this file contains the code that implements the lens effect
* (pixelized expansion) when zooming in.
*
*/
#include "mandp.h"
/* Lens algorithm:
*
* Initialization - Create RastPort and BitMap as a work area
*
* Lens Expansion -
* Phase 1 (Horizontal Expansion)
* 1. Working from left side of NavBox to Right
* 2. expand one verticle line from NavBox into temp rastport.
* 3. duplicate the line in temp rastport to expansion width
* 4. Continue for enough lines to fill the temp rastport
*
* Phase 2 (Verticle Expansion)
* 1. Working from top of temp rastport to bottom
* 2. expand one horizontal line from temp rastport into Lens
* window rastport.
* 3. duplicate the line in Lens window rastport to expansion height
* 4. Continue for enough lines in the temp rastport
*/
/* These structures are used to hold horizontally expanded view of lenz
expansion */
static struct RastPort LensRp;
static struct BitMap LensBitMap;
static LONG LensWidth, LensHeight;
UBYTE LensOK;
UBYTE LensOn = 1;
#ifdef TEMPWINDOW
#define SAFEBLIT
static struct NewWindow NewTemp = {
0,12, /* start position */
80,80, /* width, height */
(UBYTE) 0, (UBYTE) NORMALPEN,
MOUSEBUTTONS, /* IDCMP flags */
/* MandWind flags */
WINDOWDRAG | NOCAREREFRESH | SMART_REFRESH,
(struct Gadget *) NULL, /* first gadget */
(struct Image *) NULL, /* user checkmark */
(UBYTE *) NULL, /* Title */
(struct Screen *) NULL, /* pointer to screen */
(struct BitMap *) NULL, /* pointer to superbitmap */
20,20,-1,-1, /* sizing */
CUSTOMSCREEN /* type of screen */
};
static struct Window *TempWind;
#endif
AllocLensTemp( Pict )
register struct Picture *Pict;
{
LONG Plane;
PLANEPTR t;
extern struct MenuItem LensSub[];
static LensInited;
extern struct NewScreen NewScreen;
if ( !LensOn )
return;
if (LensOK == 1)
return;
if (Pict == Pict->DrawPict)
return;
#ifdef TEMPWINDOW
NewTemp.Width = Pict->Window->Width;
NewTemp.Height = Pict->DrawPict->Window->Height;
NewTemp.LeftEdge = NewScreen.Width - NewTemp.Width-2;
NewTemp.TopEdge = 0;
NewTemp.Screen = screen;
TempWind = OpenWindow( &NewTemp );
/*WindowToBack( TempWind );*/
LensOK = TempWind != NULL;
#else
if ( ! LensInited ) {
InitRastPort( &LensRp );
LensRp.BitMap = &LensBitMap;
LensInited = 1;
}
LensWidth = Pict->Window->Width;
LensHeight = Pict->DrawPict->Window->Height;
InitBitMap( &LensBitMap, (long) NewScreen.Depth, LensWidth, LensHeight);
for (Plane = 0; Plane < NewScreen.Depth; Plane++) {
t = (PLANEPTR) AllocRaster(LensWidth,LensHeight);
LensBitMap.Planes[Plane] = (PLANEPTR) t;
if (t == NULL) {
FreeLensTemp( );
return;
}
}
LensOK = 1;
#endif
}
FreeLensTemp( )
{
LONG Plane;
if (LensOK) {
#ifdef TEMPWINDOW
CloseWindow( TempWind );
#else
for (Plane = 0; Plane < LensBitMap.Depth; Plane++) {
if (LensBitMap.Planes[Plane]) {
FreeRaster( (char *) LensBitMap.Planes[Plane],
LensWidth, LensHeight);
LensBitMap.Planes[Plane] = NULL;
}
}
#endif
LensOK = 0;
}
}
#ifdef SAFEBLIT
SafeClipBlit( src_Wind, src_x, src_y,
dst_Wind, dst_x, dst_y,
width, height, min_terms,
line_no )
struct Window *src_Wind, *dst_Wind;
LONG src_x, src_y, dst_x, dst_y, width, height, min_terms;
LONG line_no;
{
if (src_x < 0 || src_x > src_Wind->Width) {
printf("Line %d Bad blit src_x %d Width %d\n",
line_no,src_x,src_Wind->Width);
return;
}
if (src_y < 0 || src_y > src_Wind->Height) {
printf("Line %d Bad blit src_y %d Height %d\n",
line_no, src_y,src_Wind->Height);
return;
}
if (width < 1 || width > src_Wind->Width) {
printf("Line %d Bad blit width %d\n",line_no, width);
return;
}
if (src_x + width > src_Wind->Width) {
printf("Line %d Blit outside %d Width %d \n",
line_no,src_x+width,src_Wind->Width);
return;
}
if (height < 1 || height > src_Wind->Height) {
printf("Line %d Bad blit height %d\n",line_no,height);
return;
}
if (src_y + height > src_Wind->Height) {
printf("Line %d Blit outside %d Height %d \n",
line_no,src_y+height,src_Wind->Height);
return;
}
ClipBlit( src_Wind->RPort, src_x, src_y,
dst_Wind->RPort, dst_x, dst_y,
width, height, min_terms);
}
#endif
/* Do Lens effect using temporary rastort, ClipBlit() with exponential
expansion */
Lens( Pict )
register struct Picture *Pict;
{
struct Picture *DrawPict;
LONG ExpFactor;
LONG MaxHeight,MaxWidth;
LONG SrcPos, SrcMax;
LONG DstPos, DstMax;
LONG EOL;
LONG NextPos, AccPos;
LONG AccExp;
LONG FirstSrc,FirstDst,NumOnes;
static LONG OldLeft,OldTop,OldExp;
LONG Top,Left,Bot,t;
struct Window *src_Wind,*dst_Wind;
struct RastPort *src_Rp, *dst_Rp, *tmp_Rp;
DrawPict = Pict->DrawPict;
if (DrawPict == NULL)
return;
CloseZoomBoxList( Pict );
src_Wind = DrawPict->Window;
dst_Wind = Pict->Window;
src_Rp = src_Wind->RPort;
dst_Rp = dst_Wind->RPort;
if (src_Rp == dst_Rp) return;
#ifdef TEMPWINDOW
tmp_Rp = TempWind->RPort;
#else
tmp_Rp = &LensRp;
#endif
if ( !LensOK )
return;
#ifndef TEMPWINDOW
SetRast( tmp_Rp, (long) NORMALPEN );
#endif
/* turn the Nav Box upside down, so the bit map is not inverted */
Top = Pict->NavTop;
Bot = Pict->NavBot;
Left = Pict->NavLeft;
if (Bot < Top) {
t = Bot;
Bot = Top;
Top = t;
}
if (Pict->NavRight < Left) {
Left = Pict->NavRight;
}
/* Do Horizontal Expansion into a temporary bitmap */
/* src = DrawPict */
/* dst = Pict */
MaxHeight = Bot - Top + 1;
if (MaxHeight == 0)
return;
DstPos = 0;
DstMax = dst_Wind->Width - Pict->LeftMarg - Pict->RightMarg;
SrcMax = src_Wind->Width - DrawPict->RightMarg;
#define SHIFT_FACTOR 8
AccExp = ((dst_Wind->Height - Pict->TopMarg - Pict->BotMarg)
<< SHIFT_FACTOR) / MaxHeight;
if (OldLeft == Left && OldTop == Top && OldExp == AccExp)
return;
Pict->Flags |= LENS_DISPLAYED;
OldLeft = Left;
OldTop = Top;
OldExp = AccExp;
AccPos = DstPos << SHIFT_FACTOR;
EOL = 0;
NumOnes = 0;
for (SrcPos = Left; SrcPos < SrcMax && ! EOL; SrcPos++) {
AccPos += AccExp;
NextPos = AccPos >> SHIFT_FACTOR;
ExpFactor = NextPos - DstPos;
/* Accumulate adjacent single line blits */
if (ExpFactor == 1) {
if (NumOnes == 0) {
FirstSrc = SrcPos;
FirstDst = DstPos;
}
NumOnes++;
} else {
/* Copy accumulated adjcent single line copies */
if (NumOnes > 0) {
#ifndef SAFEBLIT
ClipBlit( src_Rp, FirstSrc, (long) Top,
tmp_Rp, FirstDst, 0,
NumOnes, MaxHeight, (long) 0xc0 );
#else
SafeClipBlit( src_Wind, FirstSrc, Top,
TempWind, FirstDst, 0,
NumOnes, MaxHeight, 0xc0, __LINE__ );
#endif
NumOnes = 0;
}
if (ExpFactor > 1) {
register LONG WrkPos, WrkOff, Last, DstExp;
/* Expand Pattern exponentially */
WrkPos = DstPos + 1;
WrkOff = 1;
Last = 0;
DstExp = 1;
/* Copy First line */
#ifndef SAFEBLIT
ClipBlit( src_Rp, SrcPos, (long) Top,
tmp_Rp, DstPos, 0,
(long) 1, MaxHeight, (long) 0xc0 );
#else
SafeClipBlit( src_Wind, SrcPos, Top,
TempWind, DstPos, 0,
1, MaxHeight, 0xc0, __LINE__);
#endif
/* Now expand it exponentially */
do {
if ( WrkOff + DstExp >= ExpFactor ) {
Last = 1;
DstExp = ExpFactor - WrkOff;
}
if ( WrkPos + DstExp >= DstMax ) {
Last = 1;
EOL = 1;
DstExp = DstMax - WrkPos;
}
if (DstExp) {
#ifndef SAFEBLIT
ClipBlit( tmp_Rp, DstPos, 0,
tmp_Rp, WrkPos, 0,
DstExp, MaxHeight, (long) 0xc0 );
#else
SafeClipBlit( TempWind, DstPos, 0,
TempWind, WrkPos, 0,
DstExp, MaxHeight, 0xc0, __LINE__);
#endif
WrkPos += DstExp;
WrkOff += DstExp;
DstExp <<= 1;
}
} while ( ! Last );
}
}
if ((DstPos = NextPos) >= DstMax) EOL = 1;
}
if (NumOnes > 0) {
#ifndef SAFEBLIT
ClipBlit( src_Rp, FirstSrc, (long) Top,
tmp_Rp, FirstDst, 0,
NumOnes, MaxHeight, (long) 0xc0 );
#else
SafeClipBlit( src_Wind, FirstSrc, Top,
TempWind, FirstDst, 0,
NumOnes, MaxHeight, 0xc0, __LINE__);
#endif
}
NumOnes = 0;
ZoomBox( Pict );
/* src = DrawPict */
/* dst = Pict */
/* Do Verticle Expansion */
MaxWidth = dst_Wind->Width - Pict->LeftMarg - Pict->RightMarg;
DstPos = Pict->TopMarg;
DstMax = dst_Wind->Height - Pict->BotMarg;
SrcMax = src_Wind->Height;
EOL = 0;
AccPos = DstPos << SHIFT_FACTOR;
for (SrcPos = 0; SrcPos < SrcMax && !EOL; SrcPos++) {
AccPos += AccExp;
NextPos = AccPos >> SHIFT_FACTOR;
ExpFactor = NextPos - DstPos;
/* Accumulate adjacent single line blits */
if (ExpFactor == 1) {
if (NumOnes == 0) {
FirstSrc = SrcPos;
FirstDst = DstPos;
}
NumOnes++;
} else {
/* Copy accumulated adjacent single line copies */
if (NumOnes > 0) {
#ifndef SAFEBLIT
ClipBlit( tmp_Rp, 0, FirstSrc,
dst_Rp, Pict->LeftMarg, FirstDst,
MaxWidth, NumOnes, (long) 0xc0 );
#else
SafeClipBlit( TempWind, 0, FirstSrc,
dst_Wind, Pict->LeftMarg, FirstDst,
MaxWidth, NumOnes, 0xc0, __LINE__);
#endif
NumOnes = 0;
}
if ( ExpFactor > 1 ) {
register LONG WrkPos, WrkOff, Last, DstExp;
/* Expand Pattern exponentially */
WrkPos = DstPos + 1;
WrkOff = 1;
Last = 0;
DstExp = 1;
/* Copy First Horizontal Line */
#ifndef SAFEBLIT
ClipBlit( tmp_Rp, 0, SrcPos,
dst_Rp, Pict->LeftMarg, DstPos,
MaxWidth, (long) 1, (long) 0xc0 );
#else
SafeClipBlit( TempWind, 0, SrcPos,
dst_Wind, Pict->LeftMarg, DstPos,
MaxWidth, 1, 0xc0, __LINE__ );
#endif
do {
if ( WrkOff + DstExp >= ExpFactor ) {
Last = 1;
DstExp = ExpFactor - WrkOff;
}
if ( WrkPos + DstExp >= DstMax ) {
Last = 1;
EOL = 1;
DstExp = DstMax - WrkPos;
}
if (DstExp) {
#ifndef SAFEBLIT
ClipBlit( dst_Rp, Pict->LeftMarg, DstPos,
dst_Rp, Pict->LeftMarg, WrkPos,
MaxWidth, DstExp, (long) 0xc0 );
#else
SafeClipBlit( dst_Wind, Pict->LeftMarg, DstPos,
dst_Wind, Pict->LeftMarg, WrkPos,
MaxWidth, DstExp, 0xc0, __LINE__ );
#endif
WrkPos += DstExp;
WrkOff += DstExp;
DstExp <<= 1;
}
} while ( ! Last );
}
}
if ((DstPos = NextPos) >= DstMax) EOL = 1;
}
/* Copy accumulated adjacent single line copies */
if (NumOnes > 0) {
#ifndef SAFEBLIT
ClipBlit( tmp_Rp, 0, FirstSrc,
dst_Rp, Pict->LeftMarg, FirstDst,
MaxWidth,NumOnes, (long) 0xc0 );
#else
SafeClipBlit( TempWind, 0, FirstSrc,
dst_Wind, Pict->LeftMarg, FirstDst,
MaxWidth, NumOnes, 0xc0, __LINE__ );
#endif
}
ZoomBox( Pict );
}
CloseZoomBoxList( Pict )
register struct Picture *Pict;
{
register struct Node *zNode;
register struct Picture *ClosePict;
struct Picture *PictAddr();
zNode = Pict->zList.lh_Head;
while ( zNode->ln_Succ ) {
ClosePict = PictAddr( zNode );
if (Pict != ClosePict) {
CloseZoomBox(ClosePict);
}
zNode = zNode->ln_Succ;
}
}